home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 011 / dospath.cq / dospath.c
Encoding:
C/C++ Source or Header  |  1984-02-18  |  8.1 KB  |  296 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3.  
  4. /*
  5. ;;    file:    _STRING.C
  6. ;;
  7. ;; Command argument and DOS path manipulation functions. 
  8. ;; T. Jennings 7 June 83
  9. ;;
  10. ;; --------------- Command Tail Processing Functions ---------------
  11. ;;
  12. ;;    This next set of functions are meant to be used together. Examples
  13. ;;on their use follows.
  14. ;;
  15. ;;
  16. ;;int num_args(string)    Returns the number of args in the string, seperated
  17. ;;            by delims (see delim(), below). Leading delimiters
  18. ;;            are ignored.
  19. ;;
  20. ;;char *next_arg(string) Returns a pointer to the next arg, delimited 
  21. ;;            by a delim, skipping over the current arg. Use via
  22. ;;            ptr= nextarg(ptr) to skip to each argument. All 
  23. ;;            switches at the end of the current arg are skipped.
  24. ;;
  25. ;;
  26. ;;char *skip_delim(string) Skips leading delims in a string. returns a pointer.
  27. ;;
  28. ;;cpyarg(to,from)    Copies a string, up to the next delim or switch.
  29. ;;            Leading and trailing delimiters are stripped (from 
  30. ;;            the output string) and a null terminator is added.
  31. ;;
  32. ;;            after cpyarg()        FROM: foo/b foobar fipple
  33. ;;                        TO: foo
  34. ;;
  35. ;;delim(c)        Returns true if the character is a delimiter.
  36. ;;            Nulls are not considered a delimiter. The list of
  37. ;;            delimiters is contained in the array '_dlmlst', and
  38. ;;            can be changed via newdelim().
  39. ;;
  40. ;;newdelim(s)        Replace the list of delimiters. The string 's' must
  41. ;;            be less than 20 chars. (Not checked.)
  42. ;;
  43. ;;isswitch(c)        Returns true if the character is the current DOS
  44. ;;            switch character.
  45. ;;
  46. ;;char filtchar(c)    Convert a character to one legal for an MSDOS filename.
  47. ;;            Illegal characters such as switch or path seperators,
  48. ;;            control characters, etc are changed to '$'. Bit 7 is
  49. ;;            masked off. (Disallows foreign language support??)
  50. ;;
  51. ;;wild(string)        Returns true if the string contains a star or question.
  52. ;;
  53. ;;char *strip_path(out,in) Copies the disk specifier or pathname to the output
  54. ;;            array, and returns a pointer to the name in the input
  55. ;;            string.    Drive specs are considered a path, and are
  56. ;;            treated as such by DOS. Stripping "a:foo" and
  57. ;;            "bin/foo/framis.asm" result in:
  58. ;;
  59. ;;                IN:    "A:"
  60. ;;                IN:    "bin\foo"
  61. ;;
  62. ;;                OUT:    "A:"
  63. ;;                OUT:    "bin\"
  64. ;;
  65. ;;strip_switch(out,in)    Copy the switches from the in string, remove the switch
  66. ;;            character and put all the characters in the out array.
  67. ;;            Each is converted to upper case, and the string is null
  68. ;;            terminated.
  69. ;;
  70. ;;            strip_switch(s,"foo/b/f/z");
  71. ;;            s is now: "BFZ"
  72. ;;
  73. ;;ispath_delim(c)    Returns true if the character is a legal pathname
  74. ;;char c;        component seperator. The only two characters legal
  75. ;;            (here at least) are \ and-or /. For example:
  76. ;;
  77. ;;            Switch character = /
  78. ;;                ispath_delim('/') == 0
  79. ;;                ispath_delim('\\') == 1
  80. ;;            Switch character = -
  81. ;;                ispath_delim('/') == 1
  82. ;;                ispath_delim('\\') == 1
  83. ;;            Switch character = \
  84. ;;                ispath_delim('/') == 1
  85. ;;                ispath_delim('\\') == 0
  86. ;;
  87. ;;
  88. ;; --------- Command Tail Processing Examples ----------
  89. ;;
  90. ;;    This is an example of one way to use the above functions to process
  91. ;;an MSDOS program command tail. You do not need to know what the system switch
  92. ;;character or legal path seperators are. If you can't handle paths, strip them
  93. ;;off. Assume there is a pointer, p, that points to a command tail string:
  94. ;;
  95. ;;    p= "  source.ext abc.asm/v+\bin\def.com   /x/y/z"
  96. ;;
  97. ;;    p= skip_delim(p);        /* p= "source.exe abc...... */
  98. ;;
  99. ;;    p= next_arg(p);            /* p= "abc.asm/v.... "  */
  100. ;;    cpyarg(work,p);            /* work= "abc.asm"  */
  101. ;;    s= strip_path(work,p));        /* s= "abc.asm"   path= ""  */
  102. ;;    strip_switch(sw,p);        /* sw= "V"  */
  103. ;;
  104. ;;    p= next_arg(p);            /* p= "\bin\def.com"  */
  105. ;;    cpyarg(work,p);            /* work= "\bin\def.com"  */
  106. ;;    s= strip_path(path,p);        /* s= "def.com"  path= "\bin\"  */
  107. ;;    strip_switch(sw,p);        /* sw= ""  */
  108. ;;
  109. ;;    p= next_arg(p);            /* p= "/x/y/z"  */
  110. ;;    cpyarg(work,p);            /* work= ""  */
  111. ;;    s= strip_path(path,p);        /* s= ""  path= ""  */
  112. ;;    strip_switch(sw,p);        /* sw= "XYZ"  */
  113. ;;
  114. ;;    p= next_arg(p);            /* p= ""  */
  115. ;;
  116. ;;    while (num_args(p))        /* while not end of string ... */
  117. ;;    while (*p)            /* another way ... */
  118. ;;
  119. ;;
  120. ;;char *name,sw[4],path[40];
  121. ;;
  122. ;;    p= skip_delim(p);
  123. ;;    while (num_args(p) > 0) {    /* *p points to the current arg, */
  124. ;;        name= strip_path(path,p);
  125. ;;        strip_switch(sw,p);
  126. ;;        printf("Path= %s, Name= %s, Switches= %s\n",path,name,sw);
  127. ;;    }
  128. ;;
  129. */
  130. /* Return the number of args left in the string. */
  131.  
  132. num_args(string)
  133. char *string;
  134. {
  135. int count;
  136.  
  137.     count= 0;
  138.     string= (char *)skip_delim(string);    /* skip leading blanks, */
  139.     while (*string) {
  140.         ++count;            /* count one, */
  141.         string= (char *)next_arg(string); /* find next, */
  142.     }
  143.     return(count);
  144. }
  145. /* Return a pointer to the next argument in the string. */
  146.  
  147. next_arg(string)
  148. char *string;
  149. {
  150.     while ((!delim(*string)) && *string)        /* skip this one, */
  151.         ++string;                /* up to delim, */
  152.     string= (char *)skip_delim(string);        /* then skip delims, */
  153.     return(string);
  154. }
  155.  
  156. /* Skip over the leading delimiters in a string. */
  157.  
  158. skip_delim(string)
  159. char *string;
  160. {
  161.     while (delim(*string) && *string)
  162.         ++string;
  163.     return(string);
  164. }
  165. /* Copy the string to the destination array, stopping if we find one
  166. of our delimiters or switches. */
  167.  
  168. cpyarg(to,from)
  169. char *to;
  170. char *from;
  171. {
  172.     while ( (!delim(*from)) && (!isswitch(*from)) && *from) 
  173.         *to++= *from++;
  174.     *to= '\0';
  175.     return;
  176. }
  177. /* Strip any switches from the input string, put into the output array. */
  178.  
  179. strip_switch(out,in)
  180. char *out;
  181. char *in;
  182. {
  183.     while (*in && (!isswitch(*in)))        /* skip to end of string */
  184.         ++in;                /* or first switch, */
  185.  
  186.     while (*in && isswitch(*in)) {        /* copy switch args while */
  187.         ++in;
  188.         *out++ = toupper(*in);        /* stripping switch chars, */
  189.         ++in;
  190.     }
  191.     *out= '\0';                /* terminate it, */
  192.     return;
  193. }
  194. /* ----- List of legal delimiters. This is the default list ----- */
  195.  
  196. char _dlmlst[20] = { " \t,+" };    /* space, tab, comma, plus */
  197.  
  198. /* Change the list of delimiters. */
  199.  
  200. newdelim(s)
  201. char *s;
  202. {
  203.     strcpy(_dlmlst,s);
  204.     return;
  205. }
  206.  
  207. /* Return true if the character is a delimiter from the list above. */
  208.  
  209. delim(c)
  210. char c;
  211. {
  212. int i;
  213.     for (i= 0; _dlmlst[i]; ++i) {
  214.         if (c == _dlmlst[i]) return(1);
  215.     }
  216.     return(0);
  217. }
  218. /* return true if the character is the current switch character. */
  219.  
  220. isswitch(c)
  221. char c;
  222. {
  223.     return(c == _charop(0,0));
  224. }
  225. /* Clean up the character for a legal MSDOS filename. Convert undesireable
  226. characters to a dollar. */
  227.  
  228. char filtchar(c)
  229. char c;
  230. {
  231.     c&= 0x7f;            /* strip bit 7, */
  232.     if (isswitch(c) || ispath_delim(c) || (c < ' ') || (c > '~') )
  233.         c= '$';            /* dont allow illegal chars */
  234.     c= toupper(c);            /* all uppercase, */
  235.     return(c);
  236. }
  237. /* Return 1 if the string is a wild filespec. */
  238.  
  239. wild(string)
  240. char *string;
  241. {
  242. char *p;
  243.  
  244.     p= string;
  245.     while (*p) {
  246.         if (*p == '?') return(1);
  247.         if (*p == '*') return(1);
  248.         ++p;
  249.     }
  250.     return(0);                /* not wild. */
  251. }
  252. /* Strip the pathname or disk specifier from a filename, return it in a
  253. seperate array. We do this by initially copying the entire name in, then
  254. searching for the colon or slash. Right after the last one we find,
  255. stuff a null, removing the name part. 
  256.  
  257. Also return a pointer to the name part in the input name. */
  258.  
  259. strip_path(out,in)
  260. char *out;
  261. char *in;
  262. {
  263. char *name;
  264. char *endpath;
  265.  
  266.     strcpy(out,in);            /* duplicate, for working, */
  267.     name= in;            /* point to name, */
  268.     endpath= out;            /* and end of path part, */
  269.  
  270.     while (*in) {            /* look for slashes or colons, */
  271.         if (*in == ':')    {    /* if a colon, */
  272.             endpath= ++out;    /* point to name, */
  273.             name= ++in;
  274.         } else if (ispath_delim(*in)) {
  275.             endpath= ++out;    /* move the pointer up, */
  276.             name= ++in;
  277.         } else {
  278.             ++in;
  279.             ++out;
  280.         }
  281.     }
  282.     *endpath= '\0';            /* delete the name part, */
  283.     return(name);            /* return ptr to name part. */
  284. }
  285.  
  286. /* Return true if the character is a legal path name component seperator.
  287. The legal ones here are \ or /, depending on what the switch character is. */
  288.  
  289. ispath_delim(c)
  290. char c;
  291. {
  292.     if ((c == '\\') && (!isswitch('\\'))) return(1);
  293.     if ((c == '/') && (!isswitch('/'))) return(1);
  294.     return(0);
  295. }
  296.